home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / data / maglrex / magl.c next >
C/C++ Source or Header  |  1991-10-18  |  12KB  |  499 lines

  1. /*
  2.  *                        'Magl.rex'         for FM-TOWNS
  3.  *
  4.  *                - MAKIchan Graphic loader is not 鮪だ! -
  5.  *
  6.  *                    Version 1.03    Update 1991/05/12
  7.  *
  8.  *                            programmed by MALOR
  9.  */
  10.  
  11. /*
  12.  *            1991/04/25    v1.00    正常に展開されたぞ
  13.  *                 05/06    v1.01    カラーパレットの障害を修正
  14.  *                    10    v1.02    スタックにヒープを取るようにして、
  15.  *                                実行ファイル512Kの地獄を脱した(^_^;)
  16.  *                    12    v1.03    256色モードのパレットの障害を修正
  17.  *  今後の課題
  18.  */
  19.  
  20. #include <egb.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include "pixel.h"
  25.  
  26. #define VERSION    "1.03"
  27. #define UPDATE    "1991/05/12 11:28"
  28.  
  29. #define tolower(x) ((x)<'Z')&&((x)>'A')?((x)-'A'+'a'):(x)
  30.  
  31. #define FNAME16 0x0006118c
  32. #define FNAME25 0x000610fc
  33. #define FNAME32 0x000614dc
  34.  
  35. #define PALADDR16 0x00062B58    /* 16色モード時 */
  36. #define RGB2HSV16 0x0002C774
  37. #define PALADDR25 0x00062A08    /* 256色モード時 */
  38. #define RGB2HSV25 0x0002c274
  39.  
  40. #define MemorySize 512*1024        /* Buffer is 512Kbyte */
  41.  
  42. #ifndef NULL
  43. #define NULL    0
  44. #endif
  45.  
  46. #define FALSE    0
  47. #define TRUE    -1
  48. #define EOC        0x1a        /* End Of Comment */
  49. #define CR        0x0d
  50. #define LF        0x0a
  51. #define BufSize    256
  52.  
  53. #define PLANE20    0x001c
  54. #define PLANE21    0x0104
  55. #define PLANE10    0x010c
  56.  
  57. #define PALNO    0xfd90
  58. #define PALB    0xfd92
  59. #define PALR    0xfd94
  60. #define PALG    0xfd96
  61.  
  62. #define LINE200    0x01            /* 200ラインフラグ */
  63. #define COL8    0x02            /* 8色フラグ */
  64. #define DIGITAL    0x04            /* デジタルフラグ */
  65. #define COL256    0x80            /* 256色フラグ */
  66.  
  67. #define VRAM    0x20            /* 強制VRAM展開フラグ */
  68.  
  69. typedef union {
  70.     struct { unsigned char h,l; } m;
  71.     unsigned short    s;
  72.     } WORD;
  73.  
  74. typedef struct {
  75.     char    header;            /* ヘッダの先頭 */
  76.     char    machine;        /* 機種コード */
  77.     char    rflg;            /* 機種依存フラグ */
  78.     char    screen;            /* スクリーンモード */
  79.     short    lx;                /* 表示開始位置X */
  80.     short    ly;                /* 表示開始位置Y */
  81.     short    rx;                /* 表示終了位置X */
  82.     short    ry;                /* 表示終了位置Y */
  83.     int        offa;            /* フラグAのオフセット */
  84.     int        offb;            /* フラグBのオフセット */
  85.     int        sizb;            /* フラグBのサイズ */
  86.     int        offp;            /* ピクセルのオフセット */
  87.     int        sizp;            /* ピクセルのサイズ */
  88.     } MAGHEADER;
  89.  
  90. typedef struct {
  91.     char    id[8];            /* MAKI識別子'MAKI01A ' or 'MAKI01B ' */
  92.     char    comment[24];    /* セーバー作者コメント */
  93.     WORD    sizb;            /* フラグBのサイズ */
  94.     WORD    sizpa;            /* ピクセルAのサイズ */
  95.     WORD    sizpb;            /* ピクセルBのサイズ */
  96.     WORD    tile;            /* タイルデータのサイズ */
  97.     WORD    lx;                /* 表示開始位置X */
  98.     WORD    ly;                /* 表示開始位置Y */
  99.     WORD    rx;                /* 表示終了位置X */
  100.     WORD    ry;                /* 表示終了位置Y */
  101.     } MKIHEADER;
  102.  
  103. typedef struct {
  104.     unsigned short g,r,b,h,s,v;
  105.     } PALTABLE;
  106.  
  107. typedef void (*PALCONV)( int r, int g, int b, short *h, short *s, short *v );
  108.  
  109. /* Prototype declaration */
  110.  
  111. extern void    load(int dummy,int mode,char *egbwork,char *usrwork,int sx,int sy,int ex,int ey);
  112. void    load(int dummy,int mode,char *egbwork,char *usrwork,int sx,int sy,int ex,int ey);
  113. char    *getext(char *arg);
  114. int        memory_allocate(int size);
  115. int        stringcmp(char *s,char *d);
  116. int        mag_get_head(FILE *fp);
  117. int        mag_decode(FILE *fp,int mode,int x,int y);
  118. int        mki_get_head(FILE *fp);
  119. int        mki_decode(FILE *fp,int mode,int x,int y);
  120. int        set_palette(void);
  121.  
  122. /* Global Vari. */
  123.  
  124. extern char    mem[];                        /* Heap Buffer pointer */
  125. char        *egb;                        /* EGBworkへのポインタ(Global版) */
  126.  
  127. MAGHEADER    maghead;                    /* MAGのヘッダ */
  128. MKIHEADER    mkihead;                    /* MAKIのベッダ */
  129. int            sizp;                        /* MAKIのピクセルサイズ */
  130. int            siza;                        /* MAGのflag aのサイズ */
  131. int            headtop;                    /* MAGのヘッダのオフセット */
  132. char        pal[768];                    /* 現在のパレット情報 */
  133. char        *flga,*flgb,*flg,*pix;        /* flag&pixel格納アドレス */
  134. int            xpixel;                        /* 横方向のピクセル数の半分 */
  135. /* 現在メモリに存在するイメージ情報 */
  136. char        *vram=NULL;                    /* イメージ格納アドレス */
  137. int            screen_mode;                /* スクリーンモード(MAG互換) */
  138.  
  139. /* Main program */
  140.  
  141. void    load(int dummy,int mode,char *egbwork,char *usrwork,int sx,int sy,int ex,int ey)
  142. {
  143.     char *s,*d,*p,fname[BufSize];
  144.     FILE *fp;
  145.     int dx,dy,i;
  146.  
  147.     dx=0; dy=0;
  148.     egb = egbwork;
  149.  
  150.     if (mode == 4) 
  151.         p = (char *)FNAME16;
  152.     else if (mode == 8)
  153.         p = (char *)FNAME25;
  154.     else if (mode == 16)
  155.         p = (char *)FNAME32;
  156.     else
  157.         return;
  158.  
  159.     for(d=fname,s=p,i=0;i<8;i++)
  160.         *d++ = ((*s!='\0')&&(*s!='.'))?(*s++):' ';
  161.  
  162.     for(s=".mag";*s!='\0';*d++ = *s++);
  163.     *d = '\0';
  164.     if ((fp=fopen(fname,"rb"))==NULL) {
  165.         for(d=getext(fname),s="mki";*s!='\0';*d++ = *s++);
  166.         *d = '\0';
  167.         if ((fp=fopen(fname,"rb"))==NULL)
  168.             return;
  169.     }
  170.  
  171.     if (mag_get_head(fp)) {
  172.         if ((maghead.screen&COL256)&&(mode!=8))
  173.             return;
  174.         if ((!(maghead.screen&COL256))&&(mode!=4))
  175.             return;
  176.         set_palette();
  177.         /* printf("magl : start mag_decode \n"); */
  178.         mag_decode(fp,mode,dx,dy);
  179.     } else if (mki_get_head(fp)) {
  180.         if (mode!=4)
  181.             return;
  182.         set_palette();
  183.         mki_decode(fp,mode,dx,dy);
  184.     }
  185.  
  186.     fclose(fp);
  187.  
  188. }
  189.  
  190. char    *getext(char *arg)
  191. {
  192.     char *p;
  193.     
  194.     for(p=arg;*arg!='\0';arg++)
  195.         if (*arg=='\\') p=arg+1;
  196.     for(;*p!='.'&&*p!='\0';p++);
  197.     if (*p=='\0')
  198.         return NULL;
  199.     else
  200.         return p+1;
  201. }
  202.  
  203. int        memory_allocate(int size)
  204. {
  205.     static char *bottom = mem;
  206.     static int total_size = 0;
  207.  
  208.     if (total_size+size>=MemorySize)
  209.         return 0;
  210.     else {
  211.         bottom += size;
  212.         total_size += size;
  213.         return (int)bottom-size;
  214.     }
  215. }
  216.  
  217. int        stringcmp(char *s,char *d)
  218. {
  219.     for (;*s!='\0';s++,d++)
  220.         if ((tolower(*s))!=(tolower(*d)))
  221.             return FALSE;
  222.     return TRUE;
  223. }
  224.  
  225. int        mag_get_head(FILE *fp)
  226. {
  227.     char buf[10];
  228.     
  229.     fseek(fp,0,0);
  230.     fread(buf,1,8,fp);
  231.     if (!stringcmp("MAKI02",buf))
  232.         return FALSE;
  233.  
  234.     fseek(fp,0,0);
  235.  
  236.     for(headtop=0;;headtop++) {
  237.         if (fread(buf,1,1,fp)!=1)
  238.             return FALSE;
  239.         if (*buf==EOC) {
  240.             headtop++;
  241.             break;
  242.         }
  243.     }
  244.     
  245.     if (fread((char *)&maghead,1,sizeof(MAGHEADER),fp)<sizeof(MAGHEADER))
  246.         return FALSE;
  247.  
  248.     xpixel = (maghead.screen&COL256)?(maghead.rx/4-maghead.lx/4+1)
  249.                                     :(maghead.rx/8-maghead.lx/8+1);
  250.     siza = (xpixel*(maghead.ry-maghead.ly+1)+7) / 8;
  251.  
  252.     screen_mode = maghead.screen;
  253.  
  254.     fread(pal,1,(screen_mode&COL256)?768:48,fp);        /* palette read */
  255.  
  256.     return TRUE;
  257. }
  258.  
  259. int        mag_decode(FILE *fp,int mode,int x,int y)
  260. {
  261.     /* flag a size */
  262.     xpixel = (maghead.screen&COL256)?(maghead.rx/4-maghead.lx/4+1)
  263.                                     :(maghead.rx/8-maghead.lx/8+1);
  264.     siza = (xpixel*(maghead.ry-maghead.ly+1)+7) / 8;
  265.             /* xpixel = 横方向のピクセル数の半分 */
  266.  
  267.     if ((flga=(char *)memory_allocate(siza))==NULL) {
  268.         printf("magl : can't allocate memory ( flag a )\n");
  269.         goto Exit;
  270.     }
  271.  
  272.     if ((flgb=(char *)memory_allocate(maghead.sizb))==NULL) {
  273.         printf("magl : can't allocate memory ( flag b )\n");
  274.         goto Exit;
  275.     }
  276.  
  277.     if ((pix=(char *)memory_allocate(maghead.sizp))==NULL) {
  278.         printf("magl : can't allocate memory ( pixcel )\n");
  279.         goto Exit;
  280.     }
  281.  
  282.     if ((flg=(char *)memory_allocate(siza*8))==NULL) {
  283.         printf("magl : can't allocate memory ( flag )\n");
  284.         goto Exit;
  285.     }
  286.  
  287.     fseek(fp,headtop+maghead.offa,0);                /* flag a read */
  288.     if (fread(flga,1,siza,fp)!=siza)
  289.         printf("magl : inproper size ( flag a )\n");
  290.  
  291.     fseek(fp,headtop+maghead.offb,0);                /* flag b read */
  292.     if (fread(flgb,1,maghead.sizb,fp)!=maghead.sizb)
  293.         printf("magl : inproper size ( flag b )\n");
  294.  
  295.     fseek(fp,headtop+maghead.offp,0);                /* pixcel read */
  296.     if (fread(pix,1,maghead.sizp,fp)!=maghead.sizp)
  297.         printf("magl : inproper size ( pixcel )\n");
  298.  
  299.     Lineofs = (unsigned int)1024*((maghead.screen&COL256)?2:1);
  300.     Mofs[0]  = -(int)(( 0+ 0*Lineofs)/2);
  301.     Mofs[1]  = -(int)(( 4+ 0*Lineofs)/2);
  302.     Mofs[2]  = -(int)(( 8+ 0*Lineofs)/2);
  303.     Mofs[3]  = -(int)((16+ 0*Lineofs)/2);
  304.     Mofs[4]  = -(int)(( 0+ 1*Lineofs)/2);
  305.     Mofs[5]  = -(int)(( 4+ 1*Lineofs)/2);
  306.     Mofs[6]  = -(int)(( 0+ 2*Lineofs)/2);
  307.     Mofs[7]  = -(int)(( 4+ 2*Lineofs)/2);
  308.     Mofs[8]  = -(int)(( 8+ 2*Lineofs)/2);
  309.     Mofs[9]  = -(int)(( 0+ 4*Lineofs)/2);
  310.     Mofs[10] = -(int)(( 4+ 4*Lineofs)/2);
  311.     Mofs[11] = -(int)(( 8+ 4*Lineofs)/2);
  312.     Mofs[12] = -(int)(( 0+ 8*Lineofs)/2);
  313.     Mofs[13] = -(int)(( 4+ 8*Lineofs)/2);
  314.     Mofs[14] = -(int)(( 8+ 8*Lineofs)/2);
  315.     Mofs[15] = -(int)(( 0+16*Lineofs)/2);
  316.  
  317.     Lineofs /= 2;
  318.  
  319.     if ((maghead.rx-maghead.lx)>1023) {
  320.         printf("magl : picture is too wide \n");
  321.         goto Exit;
  322.     }
  323.     if ((maghead.ry-maghead.ly)>479) {
  324.         maghead.ly = 0;
  325.         maghead.ry = 479;
  326.         y = 0;
  327.     }
  328.     if ((maghead.rx+x)>1023||(maghead.ry+y)>511
  329.                 ||(maghead.lx+x)<0||(maghead.ly+y)<0) {
  330.         x = 0;
  331.         y = 0;
  332.     }
  333.     /* printf("magl : pixcel decode start\n"); */
  334.     mag((char *)(&maghead),mode|VRAM
  335.         ,(x+y*1024)/((maghead.screen&COL256)?1:2),xpixel);
  336.     /* printf("magl : pixcel decode end \n"); */
  337.  
  338. /*
  339.     free(flg);
  340.     free(pix);
  341.     free(flgb);
  342.     free(flga);
  343. */
  344.  
  345.     flg = NULL; pix = NULL; flgb = NULL; flga = NULL;
  346.  
  347.     return TRUE;
  348.  
  349. Exit:
  350. /* 
  351.     if (flg!=NULL)
  352.         free(flg);
  353.     if (pix!=NULL)
  354.         free(pix);
  355.     if (flgb!=NULL)
  356.         free(flgb);
  357.     if (flga!=NULL)
  358.         free(flga);
  359. */
  360.     flg = NULL; pix = NULL; flgb = NULL; flga = NULL;
  361.  
  362.     return FALSE;
  363. }
  364.  
  365. int        mki_get_head(FILE *fp)
  366. {
  367.     unsigned char tmp;
  368.     headtop = 0;
  369.  
  370.     fseek(fp,0,0);
  371.     if (fread((char *)&mkihead,1,sizeof(MKIHEADER),fp)<sizeof(MKIHEADER))
  372.         return FALSE;
  373.  
  374.     if ((!stringcmp("MAKI01A",mkihead.id))&&(!stringcmp("MAKI01B",mkihead.id)))
  375.         return FALSE;
  376.  
  377.     /* モトローラ形式 -> インテル形式 */
  378.     tmp              = mkihead.sizb.m.h ;
  379.     mkihead.sizb.m.h = mkihead.sizb.m.l ;
  380.     mkihead.sizb.m.l = tmp ;
  381.     tmp               = mkihead.sizpa.m.h ;
  382.     mkihead.sizpa.m.h = mkihead.sizpa.m.l ;
  383.     mkihead.sizpa.m.l = tmp ;
  384.     tmp               = mkihead.sizpb.m.h ;
  385.     mkihead.sizpb.m.h = mkihead.sizpb.m.l ;
  386.     mkihead.sizpb.m.l = tmp ;
  387.  
  388.     sizp = mkihead.sizpa.s + mkihead.sizpb.s;
  389.  
  390.     screen_mode = 0;
  391.  
  392.     fread(pal,1,48,fp);                            /* palette read */
  393.  
  394. }
  395.  
  396. int        mki_decode(FILE *fp,int mode,int x,int y)
  397. {
  398.     /* flag a size : 1000 = 320*400 / (4*4) / 8 */
  399.     if ((flga=(char *)memory_allocate(1000))==NULL) {
  400.         printf("magl : can't allocate memory ( flag a )\n");
  401.         return FALSE;
  402.     }
  403.  
  404.     if ((flgb=(char *)memory_allocate(mkihead.sizb.s))==NULL) {
  405.         printf("magl : can't allocate memory ( flag b )\n");
  406.         return FALSE;
  407.     }
  408.  
  409.     if ((pix=(char *)memory_allocate(sizp))==NULL) {
  410.         printf("magl : can't allocate memory ( pixcel )\n");
  411.         return FALSE;
  412.     }
  413.  
  414.     /* flag size : 16000 = 320*400 / 8 */
  415.     if ((flg=(char *)memory_allocate(16000))==NULL) {
  416.         printf("magl : can't allocate memory ( flag )\n");
  417.         return FALSE;
  418.     }
  419.  
  420.     fread(flga,1,1000,fp);                                /* flag a read */
  421.     fread(flgb,1,mkihead.sizb.s,fp);                    /* flag b read */
  422.     fread(pix,1,sizp,fp);                                /* pixcel read */
  423.     
  424.     if ((x+639)>1023||(y+399)>511||x<0||y<0) {
  425.         x = 0;
  426.         y = 0;
  427.     }
  428.     mki((char *)(&mkihead),mode|VRAM,(x+y*1024)/2);
  429.     /* printf("magl : mki pixcel decode end \n"); */
  430.  
  431. /*
  432.     free(flg);
  433.     free(pix);
  434.     free(flgb);
  435.     free(flga);
  436. */
  437.     return TRUE;
  438. }
  439.  
  440. int        set_palette(void)
  441. {
  442.     unsigned char *p;
  443.     int        i,r,g,b;
  444.     short    h,s,v;
  445.     PALCONV *rgb_hsv1,*rgb_hsv2;
  446.     PALTABLE *rgb_val;
  447.  
  448.     if (screen_mode&COL256) {
  449.         rgb_hsv1 = (PALCONV *)RGB2HSV25;
  450.         rgb_hsv2 = (PALCONV *)(&rgb_hsv1);
  451.         rgb_val = (PALTABLE *)PALADDR25;
  452.         for (i=0,p=(unsigned char *)pal;i<256;i++) {
  453.             g = (int)*p++;
  454.             r = (int)*p++;
  455.             b = (int)*p++;
  456.             outpb(PALNO,i);
  457.             outpb(PALB,b);
  458.             outpb(PALR,r);
  459.             outpb(PALG,g);
  460.             (*rgb_hsv2)(r,g,b,&h,&s,&v);
  461.             rgb_val->r = (unsigned short)r;
  462.             rgb_val->g = (unsigned short)g;
  463.             rgb_val->b = (unsigned short)b;
  464.             rgb_val->h = (unsigned short)h;
  465.             rgb_val->s = (unsigned short)s;
  466.             rgb_val->v = (unsigned short)v;
  467.             rgb_val += 1;
  468.         }
  469.     } else {
  470.         rgb_hsv1 = (PALCONV *)RGB2HSV16;
  471.         rgb_hsv2 = (PALCONV *)(&rgb_hsv1);
  472.         rgb_val = (PALTABLE *)PALADDR16;
  473.         for (i=0,p=(unsigned char *)pal;i<16;i++) {
  474.             g = ((int)*p++)&0xf0;
  475.             r = ((int)*p++)&0xf0;
  476.             b = ((int)*p++)&0xf0;
  477.             outpb(PALNO,i);
  478.             outpb(PALB,b);
  479.             outpb(PALR,r);
  480.             outpb(PALG,g);
  481.             if (r) r |= 0xf;
  482.             if (g) g |= 0xf;
  483.             if (b) b |= 0xf;
  484.             (*rgb_hsv2)(r,g,b,&h,&s,&v);
  485.             rgb_val->r = (unsigned short)r;
  486.             rgb_val->g = (unsigned short)g;
  487.             rgb_val->b = (unsigned short)b;
  488.             rgb_val->h = (unsigned short)h;
  489.             rgb_val->s = (unsigned short)s;
  490.             rgb_val->v = (unsigned short)v;
  491.             rgb_val += 1;
  492.         }
  493.     }
  494.  
  495.     return TRUE ;
  496.  
  497. }
  498.  
  499.